package com.study.test.dateTest;

import jodd.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Objects;

/**
 * @Author dupeng
 * @Description:
 * @Date: Create at 2018/10/14 15:48
 * @Version
 * @Modify by:
 */
public class DateUtil {

    private static Logger logger = LoggerFactory.getLogger(DateUtil.class);
    public static final long ONE_DAY_SECONDS = 86400L;
    public static final String YYYY_MM_DD = "yyyyMMdd";
    public static final String longFormat = "yyyyMMddHHmmss";
    public static final String timeFormat = "HHmmss";
    public static final String monthFormat = "yyyyMM";
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    public static final String YYYY_MM = "yyyy-MM";
    public static final String YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
    public static final String CHINESE_YYYYMM = "yyyy年MM月";
    public static final String CHINESE_YYYYMMDD = "yyyy年MM月dd日";

    public static final String MONTH_COMMA_FORMAT = "yyyy.MM";
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    public static final String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";


    public static XMLGregorianCalendar convertToXMLGregorianCalendar(Date date) {

        GregorianCalendar cal = new GregorianCalendar();
        cal.setTime(date);
        XMLGregorianCalendar gc = null;
        try {
            gc = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
        } catch (Exception e) {
            logger.error("", e);
        }
        return gc;
    }

    public static Date convertToDate(XMLGregorianCalendar cal) throws Exception {
        GregorianCalendar ca = cal.toGregorianCalendar();
        return ca.getTime();
    }

    /**
     * 给定时间是否大于 当前系统时间 ,精确到秒
     *
     * @param date
     * @return true (>) ,false (<=)
     */
    public static boolean isExpired(Date date) {
        if (null ==date) {
            throw  new IllegalArgumentException("The date must not be null");
        }
        Calendar calendar = Calendar.getInstance();
        return  calendar.getTime().after(date);


    }


    /**
     * 两个日期之间相差天数(d1 - d2)
     * @param d1
     * @param d2
     * @return
     */
    public static int getDaysDiff(Date d1, Date d2) throws Exception{
        SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
        d1 = sdf.parse(sdf.format(d1));
        d2 = sdf.parse(sdf.format(d2));
        Calendar cal = Calendar.getInstance();
        cal.setTime(d1);
        long time1 = cal.getTimeInMillis();
        cal.setTime(d2);
        long time2 = cal.getTimeInMillis();
        long diffDays = (time1-time2) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(diffDays));
    }

    /**
     * @param dateStr yyyy-MM
     * @return yyyy-MM-dd HH:mm:ss
     */
    public static Date getDateYYYYMM(String dateStr) throws Exception{
        SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM);
        return sdf.parse(dateStr);
    }


    /**
     * 获取月份第一天
     * @param dateStr yyyy-MM
     * @return yyyy-MM-dd HH:mm
     */
    public static String getMonthBegin(String dateStr) throws Exception{
        SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM);
        Date d = sdf.parse(dateStr);
        return getMonthBegin(d);
    }

    /**
     * 获取月份第一天
     * @param date
     * @return yyyy-MM-dd HH:mm
     */
    public static String getMonthBegin(Date date){
        SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM_DD_HH_MM);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return sdf.format(calendar.getTime());
    }

    /**
     * 获取当前月下一月份第一天
     * @param dateStr yyyy-MM
     * @return yyyy-MM-dd HH:mm
     */
    public static String getNextMonthBegin(String dateStr) throws Exception{
        SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM);
        Date d = sdf.parse(dateStr);
        return getNextMonthBegin(d);
    }

    /**
     * 获取当前月下一月份第一天
     * @param date
     * @return yyyy-MM-dd HH:mm
     */
    public static String getNextMonthBegin(Date date){
        SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM_DD_HH_MM);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return sdf.format(calendar.getTime());
    }

    public static DateFormat getNewDateFormat(String pattern) {
        DateFormat df = new SimpleDateFormat(pattern);
        df.setLenient(false);
        return df;
    }

    public static String format(Date date, String format) {
        return date == null ? null : (new SimpleDateFormat(format)).format(date);
    }

    public static Date parseDateNoTime(String sDate) throws ParseException {
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        if (sDate != null && sDate.length() >= "yyyyMMdd".length()) {
            if (!isNumeric(sDate)) {
                throw new ParseException("not all digit", 0);
            } else {
                return dateFormat.parse(sDate);
            }
        } else {
            throw new ParseException("length too little", 0);
        }
    }

    public static Date parseDateNoTime(String sDate, String format) throws ParseException {
        if (StringUtil.isBlank(format)) {
            throw new ParseException("Null format. ", 0);
        } else {
            DateFormat dateFormat = new SimpleDateFormat(format);
            if (sDate != null && sDate.length() >= format.length()) {
                return dateFormat.parse(sDate);
            } else {
                throw new ParseException("length too little", 0);
            }
        }
    }

    /**
     * 判断字符串是否只包含unicode数字。
     *
     * <p>
     * <code>null</code>将返回<code>false</code>，空字符串<code>""</code>将返回<code>true</code>。
     * </p>
     * <pre>
     * StringUtil.isNumeric(null)   = false
     * StringUtil.isNumeric("")     = true
     * StringUtil.isNumeric("  ")   = false
     * StringUtil.isNumeric("123")  = true
     * StringUtil.isNumeric("12 3") = false
     * StringUtil.isNumeric("ab2c") = false
     * StringUtil.isNumeric("12-3") = false
     * StringUtil.isNumeric("12.3") = false
     * </pre>
     *
     * @param str 要检查的字符串
     *
     * @return 如果字符串非<code>null</code>并且全由unicode数字组成，则返回<code>true</code>
     */
    public static boolean isNumeric(String str) {
        if (str == null) {
            return false;
        }

        int length = str.length();

        for (int i = 0; i < length; i++) {
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }

        return true;
    }
    public static Date parseDateNoTimeWithDelimit(String sDate, String delimit) throws ParseException {
        sDate = sDate.replaceAll(delimit, "");
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        if (sDate != null && sDate.length() == "yyyyMMdd".length()) {
            return dateFormat.parse(sDate);
        } else {
            throw new ParseException("length not match", 0);
        }
    }

    public static Date parseDateLongFormat(String sDate) {
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        Date d = null;
        if (sDate != null && sDate.length() == "yyyyMMddHHmmss".length()) {
            try {
                d = dateFormat.parse(sDate);
            } catch (ParseException var4) {
                return null;
            }
        }

        return d;
    }

    public static Date parseDateNewFormat(String sDate) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d = null;
        if (sDate != null && sDate.length() == "yyyy-MM-dd HH:mm:ss".length()) {
            try {
                d = dateFormat.parse(sDate);
            } catch (ParseException var4) {
                return null;
            }
        }

        return d;
    }
    public static Date parseDateFormat(String sDate,String pattrtn) {
        DateFormat dateFormat = new SimpleDateFormat(pattrtn);
        Date d = null;
        if (sDate != null ) {
            try {
                d = dateFormat.parse(sDate);
            } catch (ParseException var4) {
                return null;
            }
        }

        return d;
    }
    public static Date addHours(Date date, long hours) {
        return addMinutes(date, hours * 60L);
    }

    public static Date addMinutes(Date date, long minutes) {
        return addSeconds(date, minutes * 60L);
    }

    public static Date addSeconds(Date date1, long secs) {
        return new Date(date1.getTime() + secs * 1000L);
    }

    public static boolean isValidHour(String hourStr) {
        if (!StringUtil.isEmpty(hourStr) && isNumeric(hourStr)) {
            int hour = (new Integer(hourStr)).intValue();
            if (hour >= 0 && hour <= 23) {
                return true;
            }
        }

        return false;
    }

    public static boolean isValidMinuteOrSecond(String str) {
        if (!StringUtil.isEmpty(str) && isNumeric(str)) {
            int hour = (new Integer(str)).intValue();
            if (hour >= 0 && hour <= 59) {
                return true;
            }
        }

        return false;
    }

    public static Date addDays(Date date1, long days) {
        return addSeconds(date1, days * 86400L);
    }

    public static String getTomorrowDateString(String sDate) throws ParseException {
        Date aDate = parseDateNoTime(sDate);
        aDate = addSeconds(aDate, 86400L);
        return getDateString(aDate);
    }



    public static String getNewFormatDateString(Date date) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return getDateString(date, dateFormat);
    }

    public static String getDateString(Date date, DateFormat dateFormat) {
        return date != null && dateFormat != null ? dateFormat.format(date) : null;
    }

    public static String getYesterDayDateString(String sDate) throws ParseException {
        Date aDate = parseDateNoTime(sDate);
        aDate = addSeconds(aDate, -86400L);
        return getDateString(aDate);
    }

    public static String getDateString(Date date) {
        DateFormat df = getNewDateFormat("yyyyMMdd");
        return df.format(date);
    }

    public static String getWebDateString(Date date) {
        DateFormat dateFormat = getNewDateFormat("yyyy-MM-dd");
        return getDateString(date, dateFormat);
    }

    public static String getNoSecondDateString(Date date) {
        DateFormat dateFormat = getNewDateFormat("yyyy-MM-dd HH:mm");
        return getDateString(date, dateFormat);
    }

    public static String getChineseDateString(Date date) {
        DateFormat dateFormat = getNewDateFormat("yyyy年MM月dd日");
        return getDateString(date, dateFormat);
    }

    public static String getTodayString() {
        DateFormat dateFormat = getNewDateFormat("yyyyMMdd");
        return getDateString(new Date(), dateFormat);
    }

    public static String getTimeString(Date date) {
        DateFormat dateFormat = getNewDateFormat("HHmmss");
        return getDateString(date, dateFormat);
    }

    public static String getBeforeDayString(int days) {
        Date date = new Date(System.currentTimeMillis() - 86400000L * (long)days);
        DateFormat dateFormat = getNewDateFormat("yyyyMMdd");
        return getDateString(date, dateFormat);
    }

    public static long getDiffSeconds(Date one, Date two) {
        Calendar sysDate = new GregorianCalendar();
        sysDate.setTime(one);
        Calendar failDate = new GregorianCalendar();
        failDate.setTime(two);
        return (sysDate.getTimeInMillis() - failDate.getTimeInMillis()) / 1000L;
    }

    public static long getDiffMinutes(Date one, Date two) {
        Calendar sysDate = new GregorianCalendar();
        sysDate.setTime(one);
        Calendar failDate = new GregorianCalendar();
        failDate.setTime(two);
        return (sysDate.getTimeInMillis() - failDate.getTimeInMillis()) / 60000L;
    }

    public static long getDiffDays(Date one, Date two) {
        Calendar sysDate = new GregorianCalendar();
        sysDate.setTime(one);
        Calendar failDate = new GregorianCalendar();
        failDate.setTime(two);
        return (sysDate.getTimeInMillis() - failDate.getTimeInMillis()) / 86400000L;
    }

    public static long getDiffDaysIgnoreTime(Date one, Date two) throws ParseException {
        Date end = parseDateNoTime(getDateString(one));
        Date start = parseDateNoTime(getDateString(two));
        return getDiffDays(end, start);
    }

    public static String getBeforeDayString(String dateString, int days) {
        DateFormat df = getNewDateFormat("yyyyMMdd");

        Date date;
        try {
            date = df.parse(dateString);
        } catch (ParseException var5) {
            date = new Date();
        }

        date = new Date(date.getTime() - 86400000L * (long)days);
        return df.format(date);
    }

    public static boolean isValidShortDateFormat(String strDate) {
        if (strDate.length() != "yyyyMMdd".length()) {
            return false;
        } else {
            try {
                Integer.parseInt(strDate);
            } catch (Exception var4) {
                return false;
            }

            DateFormat df = getNewDateFormat("yyyyMMdd");

            try {
                df.parse(strDate);
                return true;
            } catch (ParseException var3) {
                return false;
            }
        }
    }

    public static boolean isValidShortDateFormat(String strDate, String delimiter) {
        String temp = strDate.replaceAll(delimiter, "");
        return isValidShortDateFormat(temp);
    }

    public static boolean isValidLongDateFormat(String strDate) {
        if (strDate.length() != "yyyyMMddHHmmss".length()) {
            return false;
        } else {
            try {
                Long.parseLong(strDate);
            } catch (Exception var4) {
                return false;
            }

            DateFormat df = getNewDateFormat("yyyyMMddHHmmss");

            try {
                df.parse(strDate);
                return true;
            } catch (ParseException var3) {
                return false;
            }
        }
    }

    public static boolean isValidLongDateFormat(String strDate, String delimiter) {
        String temp = strDate.replaceAll(delimiter, "");
        return isValidLongDateFormat(temp);
    }

    public static String getShortDateString(String strDate) {
        return getShortDateString(strDate, "-|/");
    }

    public static String getShortDateString(String strDate, String delimiter) {
        if (StringUtil.isBlank(strDate)) {
            return null;
        } else {
            String temp = strDate.replaceAll(delimiter, "");
            return isValidShortDateFormat(temp) ? temp : null;
        }
    }

    public static String getShortFirstDayOfMonth() {
        Calendar cal = Calendar.getInstance();
        Date dt = new Date();
        cal.setTime(dt);
        cal.set(5, 1);
        DateFormat df = getNewDateFormat("yyyyMMdd");
        return df.format(cal.getTime());
    }

    public static String getWebTodayString() {
        DateFormat df = getNewDateFormat("yyyy-MM-dd");
        return df.format(new Date());
    }

    public static String getWebFirstDayOfMonth() {
        Calendar cal = Calendar.getInstance();
        Date dt = new Date();
        cal.setTime(dt);
        cal.set(5, 1);
        DateFormat df = getNewDateFormat("yyyy-MM-dd");
        return df.format(cal.getTime());
    }

    public static String convert(String dateString, DateFormat formatIn, DateFormat formatOut) {
        try {
            Date date = formatIn.parse(dateString);
            return formatOut.format(date);
        } catch (ParseException var4) {
            logger.warn("convert() --- orign date error: " + dateString);
            return "";
        }
    }

    public static String convertWeb2ShortFormat(String dateString) {
        DateFormat df1 = getNewDateFormat("yyyy-MM-dd");
        DateFormat df2 = getNewDateFormat("yyyyMMdd");
        return convert(dateString, df1, df2);
    }


    public static String convert2ChineseDtFormat(String dateString) {
        DateFormat df1 = getNewDateFormat("yyyyMMdd");
        DateFormat df2 = getNewDateFormat("yyyy年MM月dd日");
        return convert(dateString, df1, df2);
    }

    public static String convertFromWebFormat(String dateString) {
        DateFormat df1 = getNewDateFormat("yyyyMMdd");
        DateFormat df2 = getNewDateFormat("yyyy-MM-dd");
        return convert(dateString, df2, df1);
    }

    public static boolean webDateNotLessThan(String date1, String date2) {
        DateFormat df = getNewDateFormat("yyyy-MM-dd");
        return dateNotLessThan(date1, date2, df);
    }

    public static boolean dateNotLessThan(String date1, String date2, DateFormat format) {
        try {
            Date d1 = format.parse(date1);
            Date d2 = format.parse(date2);
            return !d1.before(d2);
        } catch (ParseException var5) {
            logger.debug("dateNotLessThan() --- ParseException(" + date1 + ", " + date2 + ")");
            return false;
        }
    }

    public static String getEmailDate(Date today) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss");
        String todayStr = sdf.format(today);
        return todayStr;
    }

    public static String getSmsDate(Date today) {
        SimpleDateFormat sdf = new SimpleDateFormat("MM月dd日HH:mm");
        String todayStr = sdf.format(today);
        return todayStr;
    }

    public static String formatTimeRange(Date startDate, Date endDate, String format) {
        if (endDate != null && startDate != null) {
            String rt = null;
            long range = endDate.getTime() - startDate.getTime();
            long day = range / 86400000L;
            long hour = range % 86400000L / 3600000L;
            long minute = range % 3600000L / 60000L;
            if (range < 0L) {
                day = 0L;
                hour = 0L;
                minute = 0L;
            }

            rt = format.replaceAll("dd", String.valueOf(day));
            rt = rt.replaceAll("hh", String.valueOf(hour));
            rt = rt.replaceAll("mm", String.valueOf(minute));
            return rt;
        } else {
            return null;
        }
    }

    public static String formatMonth(Date date) {
        return date == null ? null : (new SimpleDateFormat("yyyyMM")).format(date);
    }

    public static Date getBeforeDate() {
        Date date = new Date();
        return new Date(date.getTime() - 86400000L);
    }

    public static Date getDayBegin(Date date) {
        DateFormat df = new SimpleDateFormat("yyyyMMdd");
        df.setLenient(false);
        String dateString = df.format(date);

        try {
            return df.parse(dateString);
        } catch (ParseException var4) {
            return date;
        }
    }

    public static boolean dateLessThanNowAddMin(Date date, long min) {
        return addMinutes(date, min).before(new Date());
    }

    public static boolean isBeforeNow(Date date) {
        if (date == null) {
            return false;
        } else {
            return date.compareTo(new Date()) < 0;
        }
    }

    public static boolean isValidate(Date requestTime, Date effectTime, Date expiredTime) {
        if (requestTime != null && effectTime != null && expiredTime != null) {
            return effectTime.compareTo(requestTime) <= 0 && expiredTime.compareTo(requestTime) >= 0;
        } else {
            return false;
        }
    }

    public static void main(String[] args) {
        System.out.println( DateUtil.format(new Date(),"yyyy年MM月dd日"));
        List<String> betweenTime = getBetweenTime("2021-08-31", "2021-08-31", "yyyy-MM-dd");
        System.out.println(betweenTime);

        List<String> betweenTime11 = getBetweenTime("2022-08-02", "2022-08-02", "yyyy-MM-dd");
        System.out.println("betweenTime11:"+betweenTime11);

        List<String> betweenTime2 = getBetweenTime("20220802", "20220802", "yyyyMMdd");
        System.out.println("betweenTime2:"+betweenTime2);

    }

    public static Date parseNoSecondFormat(String sDate) throws ParseException {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        if (sDate != null && sDate.length() >= "yyyy-MM-dd HH:mm".length()) {
            if (!isNumeric(sDate)) {
                throw new ParseException("not all digit", 0);
            } else {
                return dateFormat.parse(sDate);
            }
        } else {
            throw new ParseException("length too little", 0);
        }
    }

    public static boolean isSameDay(Date date1, Date date2) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(date1).equals(sdf.format(date2));
    }

    public static Date getCurrentTS() {
        Calendar calendar = Calendar.getInstance();
        Date date = calendar.getTime();
        return date;
    }

    public static Date getWeekBefore() {
        Calendar calendar = Calendar.getInstance();
        Date date = calendar.getTime();
        return date;
    }

    public static Date getDateNearCurrent(int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(5, days);
        Date date = calendar.getTime();
        return date;
    }

    /**
     * 获取新的日期
     * @param origDate
     * @param days
     * @return
     */
    public static Date addDays(Date origDate, int days){
        return addSeconds(origDate, days * ONE_DAY_SECONDS);
    }

    /**
     * 获取时间里的月份
     * @param date
     * @return
     */
    public static int getMonth(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int month = cal.get(Calendar.MONTH) + 1;
        return month;
    }
    /**
     * 获取时间里的月份
     * @param date
     * @return
     */
    public static int getDateInt(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dateInt = cal.get(Calendar.DATE);
        return dateInt;
    }

    public static Date strToDate(String dateStr, String formatStr) throws ParseException {
        if (StringUtil.isEmpty(dateStr)) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(formatStr);
        return df.parse(dateStr);
    }

    public static Date endDate(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.SECOND,59);
        cal.set(Calendar.MINUTE,59);
        Date endDate = cal.getTime();
        return endDate;
    }

    /**
     * 获取两个时间之间的所有年月份
     *
     * @param begDate 格式：yyyy-MM
     * @param endDate 格式：yyyy-MM
     * @return
     * @throws ParseException
     */
    public static List<String> getBetweenTime(String begDate, String endDate, String pattern) {
        if (begDate.length() != pattern.length() || endDate.length() != pattern.length()) {
            throw new RuntimeException("请保持格式统一");
        }
        try {
            List<String> dateList = new ArrayList<String>();
            // 格式化为年月
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            Calendar min = Calendar.getInstance();
            Calendar max = Calendar.getInstance();
            if (DateUtil.YYYY_MM.equals(pattern)) {
                min.setTime(sdf.parse(begDate));
                min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

                max.setTime(sdf.parse(endDate));
                max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

                Calendar curr = min;
                while (curr.before(max)) {
                    dateList.add(sdf.format(curr.getTime()));
                    curr.add(Calendar.MONTH, 1);
                }
                return dateList;
            } else if (DateUtil.DEFAULT_DATE_FORMAT.equals(pattern)) {
                min.setTime(sdf.parse(begDate));
                max.setTime(sdf.parse(endDate));
                Calendar curr = min;
                while (curr.before(max)) {
                    dateList.add(sdf.format(curr.getTime()));
                    curr.add(Calendar.DAY_OF_MONTH, 1);
                }
                if (curr.equals(max)) {
                    dateList.add(sdf.format(curr.getTime()));
                }
                return dateList;
            } else if (DateUtil.YYYY_MM_DD.equals(pattern)) {
                min.setTime(sdf.parse(begDate));
                max.setTime(sdf.parse(endDate));
                Calendar curr = min;
                while (curr.before(max)) {
                    dateList.add(sdf.format(curr.getTime()));
                    curr.add(Calendar.DAY_OF_MONTH, 1);
                }
                if (curr.equals(max)) {
                    dateList.add(sdf.format(curr.getTime()));
                }
                return dateList;
            }
        } catch (Exception e) {
            logger.error("DateUtil-getBetweenTime-Exception-{}",e);
        }
        return null;
    }

    /**
     * 获取当前时间的上一月
     * @param date
     * @return yyyy-MM
     */
    public static String getPreMonth(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(YYYY_MM);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1);
        return simpleDateFormat.format(calendar.getTime());
    }

    /**
     * 获取当前月初n个工作日后的日期(去掉周末)
     * @param currentDate
     * @return
     */
    public static Date getWorkDay(Date currentDate, Integer workDay) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(Objects.requireNonNull(parseDateFormat(getMonthBegin(currentDate), YYYY_MM_DD_HH_MM)));
        for (int i = 0; i < workDay; i++) {
            calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + 1);
            if (Calendar.SATURDAY == calendar.get(Calendar.DAY_OF_WEEK) ||
                    Calendar.SUNDAY == calendar.get(Calendar.DAY_OF_WEEK)) {
                workDay++;
            }
        }
        return calendar.getTime();
    }

    /**
     * 获取传入时间的最晚时间
     * @param date
     * @return
     */
    public static Date endOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
        calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
        calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
        return calendar.getTime();
    }

    /**
     * 获取当前月初n个工作日后的日期的最晚时间(去掉周末)
     * @return
     */
    public static Date getWorkDayEndTime(Date currentDate, Integer workDay) {
        Date date = getWorkDay(currentDate, workDay);
        return endDate(date);
    }

}
